import 'package:bookshelf/main.dart';
import 'package:bookshelf/reader/ht_result_handler.dart';
import 'package:bookshelf/reader/ji_result_handler.dart';

import '../entity/inventory_entity.dart';
import '../entity/setting_entity.dart';
import '../event/inventory_event.dart';
import '../event/read_block_event.dart';
import 'send_helper.dart';
import 'socket_helper.dart';

class ReaderManager {

  late ReaderManager manager;

  ReaderManager getManager(){
    return manager;
  }

  factory ReaderManager() => _singleton;

  static final ReaderManager _singleton = ReaderManager._internal();

  ReaderManager._internal();


  HTResultHandler htResultHandler = HTResultHandler();
  JiResultHandler jiResultHandler = JiResultHandler();
  List<String> readerIds = [];
  List<(String?,String?,String?)> list = [];

  startInventory(SettingEntityPlace entity) async {
    list.clear();

    if(settingEntity.readerType == 'ht_tcp'){
      SocketHelper socketHelper = SocketHelper(entity.readerAddr!);
      Future.delayed(const Duration(milliseconds: 200),(){
        socketHelper.sendData(inventoryWithAnt(entity.ant!));
      });
    }

    if(settingEntity.readerType == 'ji_serial'){
      readerIds.clear();
      readerIds.add(entity.readerId!);
      var data = await inventoryWithAnts([entity.readerId!]);
      hfSerialPortHelper.sendData(data);
    }
  }

  startInventoryWithKnot({String? readerAddr = '',List<String>? ids}) async {
    list.clear();

    if(settingEntity.readerType == 'ht_tcp'){
      SocketHelper socketHelper = SocketHelper(readerAddr!);
      Future.delayed(const Duration(milliseconds: 200),(){
        socketHelper.sendData(inventoryAll());
      });
    }

    if(settingEntity.readerType == 'ji_serial'){
      readerIds.clear();
      readerIds.addAll(ids!);
      var data = await inventoryWithAnts(ids);
      hfSerialPortHelper.sendData(data);
    }
  }

  List<SettingEntityReader> readers = [];

  startInventoryAll() async {
    list.clear();
    if(settingEntity.readerType == 'ht_tcp'){
      readers.clear();
      if(settingEntity.reader != null){
        for (var element in settingEntity.reader!) {
          if(element.state == 0){
            readers.add((element));
          }
        }
      }
      if(readers.isNotEmpty ){
        SocketHelper socketHelper = SocketHelper(readers[0].readerAddr!);
        Future.delayed(const Duration(milliseconds: 200),(){
          socketHelper.sendData(inventoryAll());
        });
      }
    }

    if(settingEntity.readerType == 'ji_serial'){
      readerIds.clear();
      if(settingEntity.place != null){
        for (var element in settingEntity.place!) {
          readerIds.add((element.readerId!));
        }
      }
      var data = await inventoryWithAnts(readerIds);
      hfSerialPortHelper.sendData(data);
    }
  }

  dataReceived(String result,{String? ip}){
    if(settingEntity.readerType == 'ht_tcp'){
      htResultHandler.dataReceived(result, ip);
    }
    if(settingEntity.readerType == 'ji_serial'){
      jiResultHandler.dataReceived(result);
    }
  }

  inventorySuccess(List<(String?,String?,String?)> data){
    if(settingEntity.readerType == 'ht_tcp'){
      list.addAll(data);
      if(readers.isNotEmpty){
        readers.removeWhere((ele) => ele.readerAddr == data[0].$3);
      }
      if(readers.isEmpty){
        eventFactory.fire(InventoryEvent(list));
      }else{
        SocketHelper socketHelper = SocketHelper(readers[0].readerAddr!);
        Future.delayed(const Duration(milliseconds: 200),(){
          socketHelper.sendData(inventoryAll());
        });
      }
    }
    if(settingEntity.readerType == 'ji_serial'){
      if(data.isNotEmpty){
        if(data[0].$1 != null){
          list.addAll(data);
        }
        readerIds.removeWhere((readerId) => readerId == data[0].$2);
      }
      if(readerIds.isEmpty){
        eventFactory.fire(InventoryEvent(list));
      }
    }
  }


  startReadBlock(InventoryEntity entity) async {
    if(settingEntity.readerType == 'ht_tcp'){
      SocketHelper socketHelper = SocketHelper(entity.readerAddr!);
      socketHelper.sendData(readBlock(entity.uid!, entity.ant!));
    }
    if(settingEntity.readerType == 'ji_serial'){
      var data = await readBlocksWithReaderId(entity.uid!, entity.ant!);
      hfSerialPortHelper.sendData(data);
    }
  }

  readBlockSuccess(no){
    eventFactory.fire(ReadBlockEvent(no));
  }

  clear(){
    htResultHandler.clear();
    jiResultHandler.clear();
  }

  getCurrentPlace(element){
    String? currentPlace;
    if(settingEntity.readerType == 'ht_tcp'){

      currentPlace = settingEntity.place!.firstWhere((e) => (e.readerAddr == element.$3)
          && (e.ant!.padLeft(2,'0') == int.parse(element.$2,radix: 16).toString().padLeft(2,'0'))).place;
    }
    if(settingEntity.readerType == 'ji_serial'){
      currentPlace = currentPlace = settingEntity.place!.firstWhere((e) => (e.readerId!.padLeft(4,'0') == element.$2.padLeft(4,'0'))).place;
    }
    return currentPlace;
  }

  sendEmpty(){

    if(settingEntity.readerType == 'ht_tcp'){
      readers.clear();
      if(settingEntity.reader != null){
        for (var element in settingEntity.reader!) {
          if(element.state == 0){
            readers.add((element));
          }
        }
      }
      for (var element in readers) {
        SocketHelper socketHelper = SocketHelper(element.readerAddr!);
        socketHelper.sendData(empty());
        print('${element.readerAddr} inventory but is not first page');
      }
    }
  }

}